#include "serialmanager.h"

SerialManager::SerialManager(QObject *parent)
    : QObject(parent)
    , serialPort_(new QSerialPort(this))
{
    connect(serialPort_, &QSerialPort::readyRead, this, &SerialManager::onReadyRead);
    connect(serialPort_, &QSerialPort::errorOccurred, this, &SerialManager::handleError);
}

SerialManager::~SerialManager()
{
    closeSerialPort();
}

void SerialManager::autoFillSerialPorts(QComboBox *comboBox)
{
    comboBox->clear();
    const QList<QSerialPortInfo> portInfos = QSerialPortInfo::availablePorts();

    if (portInfos.isEmpty()) {
        comboBox->addItem("无可用串口");
        return;
    }

    QMap<int, QString> portMap;
    for (const QSerialPortInfo &info : portInfos) {
        QString portName = info.portName();
        int portNumber = portName.mid(3).toInt();
        portMap[portNumber] = portName;
    }

    for (const QString &portName : portMap)
        comboBox->addItem(portName);

    if (comboBox->count() == 0)
        comboBox->addItem("无可用串口（无权限或被占用）");
}

bool SerialManager::openSerialPort(const SerialParams &params)
{
    if (serialPort_->isOpen())
        closeSerialPort();

    serialPort_->setPortName(params.portName);

    if (!serialPort_->setBaudRate(params.baudRate)) {
        lastError_ = "设置波特率失败";
        return false;
    }

    switch (params.dataBits) {
    case 5: serialPort_->setDataBits(QSerialPort::Data5); break;
    case 6: serialPort_->setDataBits(QSerialPort::Data6); break;
    case 7: serialPort_->setDataBits(QSerialPort::Data7); break;
    case 8: serialPort_->setDataBits(QSerialPort::Data8); break;
    default:
        lastError_ = "无效的数据位";
        return false;
    }

    if (params.parity == "无校验")
        serialPort_->setParity(QSerialPort::NoParity);
    else if (params.parity == "奇校验")
        serialPort_->setParity(QSerialPort::OddParity);
    else if (params.parity == "偶校验")
        serialPort_->setParity(QSerialPort::EvenParity);
    else {
        lastError_ = "无效的校验位";
        return false;
    }

    if (params.stopBits == "1")
        serialPort_->setStopBits(QSerialPort::OneStop);
    else if (params.stopBits == "2")
        serialPort_->setStopBits(QSerialPort::TwoStop);
    else {
        lastError_ = "无效的停止位";
        return false;
    }

    serialPort_->setFlowControl(QSerialPort::NoFlowControl);

    if (serialPort_->open(QIODevice::ReadWrite)) {
        emit connectionStatusChanged(true, QDateTime::currentDateTime());
        return true;
    } else {
        lastError_ = serialPort_->errorString();
        return false;
    }
}

void SerialManager::closeSerialPort()
{
    if (serialPort_->isOpen()) {
        serialPort_->close();
    }
    emit connectionStatusChanged(false, QDateTime::currentDateTime());
}

qint64 SerialManager::writeData(const QByteArray &data)
{
    if (!serialPort_->isOpen()) {
        lastError_ = "串口未打开";
        return -1;
    }
    return serialPort_->write(data);
}

QString SerialManager::lastError() const
{
    return lastError_;
}

QString SerialManager::currentPortName() const
{
    return serialPort_->portName();
}

bool SerialManager::isOpen() const
{
    return serialPort_->isOpen();
}

void SerialManager::onReadyRead()
{
    emit dataReady(serialPort_->readAll());
}

void SerialManager::handleError(QSerialPort::SerialPortError error)
{
    if (error == QSerialPort::ResourceError) {
        lastError_ = "串口连接丢失";
        closeSerialPort();
        emit errorOccurred(lastError_);
    }
}
